home *** CD-ROM | disk | FTP | other *** search
- #ifndef lint
- static char *sccsid = "%W% MS/ACF %E%";
- #endif
- #ifdef SUNOS41 /* wht@n4hgf2 */
- #include <stdio.h>
- runslip()
- {
- fprintf(stderr,"Sorry, not working in this OS\n");
- return(1);
- }
- abort_slip()
- {
- }
- #else /* wht@n4hgf2 */
- /*
- * tip/slip.c
- *
- * This file contains the SLIP specific startup code. It is designed
- * with both BSD sockets and Sun Streams in mind, though the socket
- * version has not been tested lately (but it SHOULD work). The Streams
- * code is for SunOS 4.0[.1].
- *
- * The code to set the route (basically an internal shell script) may
- * need tweeking on other systems, though it works on any of the
- * systems I have run into.
- *
- * The alarm/DCD code is a HACK to detect loss of the line in the
- * absense of proper modems status signaling (broken in SunOS when
- * using the dialout device, serial line minor devices 128-255).
- * This has been reported, but I suspect that a fix will have to
- * wait for SunOS 4.2 or maybe 4.1.?.
- *
- * Doug Kingston <dpk@morgan.com>
- * 880219
- */
-
- #include "tip.h"
-
- #include <sys/socket.h>
- #ifdef STREAMS
- #include <sys/stropts.h>
- #include <sys/sockio.h>
- #include <sys/termios.h> /* has defines that clash with ioctl.h */
- #include <sys/slip.h>
- #endif STREAMS
- #include <netinet/in.h>
- #include <net/if.h>
-
- #include <arpa/inet.h>
-
- #define DCD_SETTLING_TIME 1 /* time between DCD change and status check */
- #define DCD_CHECK_INTERVAL 15 /* if > 0, time between automatic DCD checks */
-
- int gotsig = 0;
- sigfunc_t dcd_handler();
-
- runslip()
- {
- int unit, s;
- struct ifreq ifr;
- #ifdef STREAMS /* Using streams */
- struct termios tios;
-
- /* pop all streams modules */
- while (ioctl(FD, I_POP, 0) == 0)
- continue;
-
- /* set up the line parameters */
- if (ioctl(FD, TCGETS, (caddr_t)&tios) < 0) {
- perror("ioctl (TCGETS)");
- return(1);
- }
- tios.c_cflag = (tios.c_cflag&(CBAUD|CIBAUD))|CS8|CREAD|HUPCL;
- tios.c_iflag = IGNBRK;
- if (ioctl(FD, TCSETS, (caddr_t)&tios) < 0) {
- perror("ioctl (TCSETS)");
- return(1);
- }
-
- /* push the SLIP module */
- if (ioctl(FD, I_PUSH, "slip") < 0) {
- perror("ioctl (I_PUSH)");
- return(1);
- }
-
- /* find out what unit number we were assigned */
- if (ioctl(FD, SLIOGUNIT, (caddr_t)&unit) < 0) {
- perror("ioctl (SLIOGUNIT)");
- return(1);
- }
- #else /* not streams */
- int ldisc = SLIPDISC;
- if (ioctl(FD, TIOCSETD, &ldisc) < 0) {
- perror("slipd: TIOCSETD");
- return(1);
- }
- if (ioctl(FD, TIOCGETD, &unit) < 0) { /* Hack to get slip number */
- perror("slipd: TIOCGETD");
- return(1);
- }
- #endif I_POP
-
- /* set the local and remote interface addresses */
- s = socket(AF_INET, SOCK_DGRAM, 0);
-
- (void) sprintf(ifr.ifr_name, "slip%d", unit);
- if (in_getaddr(DA, &ifr.ifr_addr) != 0 ||
- ioctl(s, SIOCSIFDSTADDR, (caddr_t)&ifr) < 0) {
- perror("ioctl (SIOCSIFDSTADDR)");
- return(1);
- }
-
- /* this has the side-effect of marking the interface up */
- if (in_getaddr(SA, &ifr.ifr_addr) != 0 ||
- ioctl(s, SIOCSIFADDR, (caddr_t)&ifr) < 0) {
- perror("ioctl (SIOCSIFADDR)");
- return(1);
- }
-
- if (in_getaddr(SM, &ifr.ifr_addr) != 0) {
- if (ioctl(s, SIOCSIFNETMASK, (caddr_t)&ifr) < 0) {
- perror("ioctl (SIOCSIFADDR)");
- return(1);
- }
- }
-
- /* Set up default route if desired and not already present */
- if (boolean(value(SETROUTE))) {
- char buf[256];
- char *argv[4];
- char *envp[2];
- int status;
-
- sprintf(buf, "if eval 'netstat -r|grep -s \"^default\"';\
- then echo default route already installed;\
- else route add 0 %s 3; fi", SA);
- argv[0] = "/bin/sh";
- argv[1] = "-c";
- argv[2] = buf;
- argv[3] = (char *)0;
-
- envp[0] = "PATH=/bin:/usr/bin:/usr/ucb:/etc:/usr/etc";
- envp[1] = (char *)0;
-
- switch (fork()) {
- case 0: /* Child */
- execve(argv[0], argv, envp);
- exit(1);
- case -1:
- perror("tip: route add: fork");
- break;
- default: /* Parent */
- wait(&status);
- }
- }
-
- fprintf(stderr, "\07[SLIP running]\r\n");
-
- /* set up signal handlers */
- (void) sigblock(sigmask(SIGALRM));
- (void) signal(SIGALRM, dcd_handler);
- #if defined(SIGDCD) && SIGDCD > 0
- (void) signal(SIGDCD, dcd_handler);
- #endif
-
- /* twiddle thumbs until we get a signal */
- while (1) {
- alarm(DCD_CHECK_INTERVAL);
- sigpause(0);
- #if defined(SIGDCD) && SIGDCD > 0
- (void) sigblock(sigmask(SIGALRM)|sigmask(SIGDCD));
- #else
- (void) sigblock(sigmask(SIGALRM));
- #endif SIGDCD
- if (gotsig && lowdcd(FD)) {
- sleep(DCD_SETTLING_TIME);
- if (lowdcd(FD))
- break;
- }
- gotsig = 0;
- }
- return(0);
- }
-
- abort_slip()
- {
- #ifdef STREAMS
- /* pop the SLIP stream module */
- while(ioctl(FD, I_POP, 0) == 0);
- #else
- int ldisc = 0;
- (void)ioctl(FD, TIOCSETD, &ldisc);
- #endif
- }
-
- sigfunc_t
- dcd_handler()
- {
- gotsig = 1;
- }
-
- /* Use TIOCMGET to test if DCD is low on the port of the passed descriptor */
- int
- lowdcd(fd)
- int fd;
- {
- int mbits;
-
- if (ioctl(fd, TIOCMGET, (caddr_t)&mbits) < 0)
- return 1; /* port is dead, we die */
- return !(mbits & TIOCM_CAR);
- }
-
- in_getaddr(s, saddr)
- char *s;
- struct sockaddr *saddr;
- {
- register struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
- struct hostent *hp;
- struct netent *np;
- int val;
-
- sin->sin_family = AF_INET;
- val = inet_addr(s);
- if (val != -1) {
- sin->sin_addr.s_addr = val;
- return(0);
- }
- hp = gethostbyname(s);
- if (hp) {
- sin->sin_family = hp->h_addrtype;
- bcopy(hp->h_addr, (char *)&sin->sin_addr, hp->h_length);
- return(0);
- }
- np = getnetbyname(s);
- if (np) {
- sin->sin_family = np->n_addrtype;
- sin->sin_addr = inet_makeaddr(np->n_net, INADDR_ANY);
- return(0);
- }
- fprintf(stderr, "tip: in_getaddr: can't parse/lookup '%s'\n", s);
- return(1);
- }
- #endif /* wht@n4hgf2 */
-